Skip to content

Conversation

@FarhanAnjum-opti
Copy link
Contributor

@FarhanAnjum-opti FarhanAnjum-opti commented Sep 24, 2025

Summary

Decision Service methods to handle CMAB

Test plan

Added unit tests

Issues

FSSDK-11170

…ations over CMAB service decisions in DecisionService
Copy link
Contributor

@muzahidul-opti muzahidul-opti left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Changes look good to me. Added few comments.

Copy link
Contributor

@muzahidul-opti muzahidul-opti left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

Copy link
Contributor

@jaeopt jaeopt left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A few changes in API definitions. Can you refactor them first?
I need more time to review the cmab logic.

String flagKey = flagsWithoutForcedDecision.get(i).getKey();

if (error) {
OptimizelyDecision optimizelyDecision = OptimizelyDecision.newErrorDecision(flagKey, user, DecisionMessage.CMAB_ERROR.reason(experimentKey));
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we always report CMAB error for any decision errors? Is this safe?

Copy link
Contributor Author

@FarhanAnjum-opti FarhanAnjum-opti Oct 15, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As far as I understand, we get error from decision service only when cmab fails. So this error flag is only true for cmab errors. @raju-opti can verify.

Copy link
Contributor

@jaeopt jaeopt left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A few more suggestions at the top level.

Co-authored-by: Jae Kim <45045038+jaeopt@users.noreply.github.com>
FarhanAnjum-opti and others added 7 commits October 23, 2025 20:54
Co-authored-by: Jae Kim <45045038+jaeopt@users.noreply.github.com>
Co-authored-by: Jae Kim <45045038+jaeopt@users.noreply.github.com>
…ckage-private and add copyright notice to DecisionPath
…and OptimizelyUserContext with corresponding tests
…and enhance builder methods for cache configuration
Copy link
Contributor

@jaeopt jaeopt left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see it's now more aligned with android-sdk. I added more comments. Let's discuss.


if (decision != null) {
decisions.add(new DecisionResponse(decision, reasons));
decisions.add(new DecisionResponse(decision, reasons, error, decision.cmabUUID));
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we have any case we need pass cmabUUID separately though it's already in decision?

Copy link
Contributor

@jaeopt jaeopt left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Bucket cleaning up looks good! A few more changes suggested.

Comment on lines +60 to +62
import static org.mockito.Matchers.any;
import static org.mockito.Matchers.anyObject;
import static org.mockito.Matchers.eq;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

these changes not used? clean up.

*/
package com.optimizely.ab.internal;

public interface CacheWithRemove<T> extends Cache<T> {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

java supports default implementation for interface -
We can remove CacheWithRemove and add remove() to Cache, so backward compatible with existing Cache

default void remove(String key) {
    // Default implementation does nothing
    // Implementations should override this method to provide actual removal functionality
}

public class DefaultCmabService implements CmabService {

private final DefaultLRUCache<CmabCacheValue> cmabCache;
public static final int DEFAULT_CMAB_CACHE_SIZE = 1000;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
public static final int DEFAULT_CMAB_CACHE_SIZE = 1000;
public static final int DEFAULT_CMAB_CACHE_SIZE = 10000;

Should be consistent with other server-sdks


private final DefaultLRUCache<CmabCacheValue> cmabCache;
public static final int DEFAULT_CMAB_CACHE_SIZE = 1000;
public static final int DEFAULT_CMAB_CACHE_TIMEOUT_SECS = 300; // 5 minutes
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
public static final int DEFAULT_CMAB_CACHE_TIMEOUT_SECS = 300; // 5 minutes
public static final int DEFAULT_CMAB_CACHE_TIMEOUT_SECS = 30*60; // 30 minutes

Should be consistent with other server-sdks

/**
* Set the timeout duration for cached CMAB decisions.
*
* Default value is 300 seconds (5 minutes).
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fix this comment too

/**
* Set the maximum size of the CMAB cache.
*
* Default value is 1000 entries.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fxi this comment too

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants